`include "define.v"
module EX_MEM
(
    input   wire                clk,
    input   wire                rstn,
    input   wire                flush,
    input   wire                stall,
    //
    input   wire                EX_MEM_BUBBLE_FLAG_i,
    input   wire                EX_MEM_ILLEGAL_INSTR_FLAG_i,
    input   wire    [31:00]     EX_MEM_INSTR_i,
    input   wire    [63:00]     EX_MEM_PC_i  ,
    input   wire    [02:00]     EX_MEM_FUNCT3_i,
    input   wire                EX_MEM_INSTR_LOAD_i,
    input   wire                EX_MEM_INSTR_STORE_i,
    input   wire                EX_MEM_INSTR_SYSTEM_i,
    //
    input   wire                EX_MEM_GPR_WRITE_BACK_EN_i,
    input   wire    [04:00]     EX_MEM_GPR_WRITE_BACK_ID_i,
    input   wire                EX_MEM_GPR_WRITE_BACK_FROM_ALU_i,
    input   wire                EX_MEM_GPR_WRITE_BACK_FROM_LSU_i,
    input   wire                EX_MEM_GPR_WRITE_BACK_FROM_MDU_i,
    input   wire                EX_MEM_CSR_WRITE_BACK_EN_i,
    input   wire    [11:00]     EX_MEM_CSR_WRITE_BACK_ID_i,

    // Data
    input   wire    [63:00]     EX_MEM_RS2_DATA_i,
    input   wire    [63:00]     EX_MEM_ALU_OUTPUT_i,
    input   wire    [63:00]     EX_MEM_MDU_OUTPUT_i,
    input   wire    [63:00]     EX_MEM_CSR_WRITE_BACK_DATA_i,
    
//--------------------------------------------------------
    output  reg                 EX_MEM_BUBBLE_FLAG_o,
    output  reg                 EX_MEM_ILLEGAL_INSTR_FLAG_o,
    output  reg     [31:00]     EX_MEM_INSTR_o,
    output  reg     [63:00]     EX_MEM_PC_o  ,
    output  reg     [02:00]     EX_MEM_FUNCT3_o, 
    output  reg                 EX_MEM_INSTR_LOAD_o,
    output  reg                 EX_MEM_INSTR_STORE_o,
    output  reg                 EX_MEM_INSTR_SYSTEM_o,                                                    
    //
    output  reg                 EX_MEM_GPR_WRITE_BACK_EN_o,                   
    output  reg     [04:00]     EX_MEM_GPR_WRITE_BACK_ID_o,
    output  reg                 EX_MEM_GPR_WRITE_BACK_FROM_ALU_o,
    output  reg                 EX_MEM_GPR_WRITE_BACK_FROM_LSU_o,
    output  reg                 EX_MEM_GPR_WRITE_BACK_FROM_MDU_o,
    output  reg                 EX_MEM_CSR_WRITE_BACK_EN_o,                   
    output  reg     [11:00]     EX_MEM_CSR_WRITE_BACK_ID_o,
                                         
    // Data
    output  reg     [63:00]     EX_MEM_RS2_DATA_o,
    output  reg     [63:00]     EX_MEM_ALU_OUTPUT_o,
    output  reg     [63:00]     EX_MEM_MDU_OUTPUT_o,                                    
    output  reg     [63:00]     EX_MEM_CSR_WRITE_BACK_DATA_o                      
);
    always @(posedge clk ) begin
        if (!rstn | flush) begin
            EX_MEM_BUBBLE_FLAG_o                                        <=  1'b1;        // flush后产生气泡 
            EX_MEM_ILLEGAL_INSTR_FLAG_o                                 <=  1'b0;
            EX_MEM_INSTR_o                                              <=  `BUBBLE;
            EX_MEM_PC_o                                                 <=  64'b0;     
            EX_MEM_FUNCT3_o                                             <=  3'b0; 
            EX_MEM_INSTR_LOAD_o                                         <=  1'b0;                    
            EX_MEM_INSTR_STORE_o                                        <=  1'b0;
            EX_MEM_INSTR_SYSTEM_o                                       <=  1'b0;                        
            EX_MEM_GPR_WRITE_BACK_EN_o                                  <=  1'b0;      
            EX_MEM_GPR_WRITE_BACK_ID_o                                  <=  5'b0;
            EX_MEM_GPR_WRITE_BACK_FROM_ALU_o                            <=  1'b0;
            EX_MEM_GPR_WRITE_BACK_FROM_LSU_o                            <=  1'b0;
            EX_MEM_GPR_WRITE_BACK_FROM_MDU_o                            <=  1'b0;      
            EX_MEM_CSR_WRITE_BACK_EN_o                                  <=  1'b0;      
            EX_MEM_CSR_WRITE_BACK_ID_o                                  <=  12'b0;
            EX_MEM_RS2_DATA_o                                           <=  64'b0;
            EX_MEM_ALU_OUTPUT_o                                         <=  64'b0;
            EX_MEM_MDU_OUTPUT_o                                         <=  64'b0;
            EX_MEM_CSR_WRITE_BACK_DATA_o                                <=  64'b0;        
        end
        else if( stall ) begin
            EX_MEM_BUBBLE_FLAG_o                                        <=  EX_MEM_BUBBLE_FLAG_o;
            EX_MEM_ILLEGAL_INSTR_FLAG_o                                 <=  EX_MEM_ILLEGAL_INSTR_FLAG_o; 
            EX_MEM_INSTR_o                                              <=  EX_MEM_INSTR_o;
            EX_MEM_PC_o                                                 <=  EX_MEM_PC_o;
            EX_MEM_FUNCT3_o                                             <=  EX_MEM_FUNCT3_o ;
            EX_MEM_INSTR_LOAD_o                                         <=  EX_MEM_INSTR_LOAD_o;                    
            EX_MEM_INSTR_STORE_o                                        <=  EX_MEM_INSTR_STORE_o;
            EX_MEM_INSTR_SYSTEM_o                                       <=  EX_MEM_INSTR_SYSTEM_o;                                       
            EX_MEM_GPR_WRITE_BACK_EN_o                                  <=  EX_MEM_GPR_WRITE_BACK_EN_o;      
            EX_MEM_GPR_WRITE_BACK_ID_o                                  <=  EX_MEM_GPR_WRITE_BACK_ID_o;
            EX_MEM_GPR_WRITE_BACK_FROM_ALU_o                            <=  EX_MEM_GPR_WRITE_BACK_FROM_ALU_o;
            EX_MEM_GPR_WRITE_BACK_FROM_LSU_o                            <=  EX_MEM_GPR_WRITE_BACK_FROM_LSU_o;
            EX_MEM_GPR_WRITE_BACK_FROM_MDU_o                            <=  EX_MEM_GPR_WRITE_BACK_FROM_MDU_o;      
            EX_MEM_CSR_WRITE_BACK_EN_o                                  <=  EX_MEM_CSR_WRITE_BACK_EN_o;      
            EX_MEM_CSR_WRITE_BACK_ID_o                                  <=  EX_MEM_CSR_WRITE_BACK_ID_o;
            EX_MEM_RS2_DATA_o                                           <=  EX_MEM_RS2_DATA_o;
            EX_MEM_ALU_OUTPUT_o                                         <=  EX_MEM_ALU_OUTPUT_o; 
            EX_MEM_MDU_OUTPUT_o                                         <=  EX_MEM_MDU_OUTPUT_o;                                         
            EX_MEM_CSR_WRITE_BACK_DATA_o                                <=  EX_MEM_CSR_WRITE_BACK_DATA_o;
        end
        else    begin
            EX_MEM_BUBBLE_FLAG_o                                        <=  EX_MEM_BUBBLE_FLAG_i;
            EX_MEM_ILLEGAL_INSTR_FLAG_o                                 <=  EX_MEM_ILLEGAL_INSTR_FLAG_i; 
            EX_MEM_INSTR_o                                              <=  EX_MEM_INSTR_i;
            EX_MEM_PC_o                                                 <=  EX_MEM_PC_i;  
            EX_MEM_FUNCT3_o                                             <=  EX_MEM_FUNCT3_i ;
            EX_MEM_INSTR_LOAD_o                                         <=  EX_MEM_INSTR_LOAD_i;                    
            EX_MEM_INSTR_STORE_o                                        <=  EX_MEM_INSTR_STORE_i;
            EX_MEM_INSTR_SYSTEM_o                                       <=  EX_MEM_INSTR_SYSTEM_i;                                          
            EX_MEM_GPR_WRITE_BACK_EN_o                                  <=  EX_MEM_GPR_WRITE_BACK_EN_i;      
            EX_MEM_GPR_WRITE_BACK_ID_o                                  <=  EX_MEM_GPR_WRITE_BACK_ID_i;
            EX_MEM_GPR_WRITE_BACK_FROM_ALU_o                            <=  EX_MEM_GPR_WRITE_BACK_FROM_ALU_i;
            EX_MEM_GPR_WRITE_BACK_FROM_LSU_o                            <=  EX_MEM_GPR_WRITE_BACK_FROM_LSU_i;
            EX_MEM_GPR_WRITE_BACK_FROM_MDU_o                            <=  EX_MEM_GPR_WRITE_BACK_FROM_MDU_i;      
            EX_MEM_CSR_WRITE_BACK_EN_o                                  <=  EX_MEM_CSR_WRITE_BACK_EN_i;      
            EX_MEM_CSR_WRITE_BACK_ID_o                                  <=  EX_MEM_CSR_WRITE_BACK_ID_i;
            EX_MEM_RS2_DATA_o                                           <=  EX_MEM_RS2_DATA_i;
            EX_MEM_ALU_OUTPUT_o                                         <=  EX_MEM_ALU_OUTPUT_i;
            EX_MEM_MDU_OUTPUT_o                                         <=  EX_MEM_MDU_OUTPUT_i;                   
            EX_MEM_CSR_WRITE_BACK_DATA_o                                <=  EX_MEM_CSR_WRITE_BACK_DATA_i;
        end  
    end

endmodule